﻿//// web worker is isolated from the main browser context so all scripts need to be loaded again)
//importScripts('/Game/GetResource?resourceID=c80ef4d7-86e9-4332-9238-58d14015a6df&contentType=text%2Fjavascript');
//importScripts('/Game/GetResource?resourceID=38793edf-2ef9-4422-a37d-e960cc811c71&contentType=text%2Fjavascript',
//              '/Game/GetResource?resourceID=46e475bf-22ad-463e-a326-a9c2f90fa391&contentType=text%2Fjavascript',
//              '/Game/GetResource?resourceID=5952650d-1e18-43f6-9134-1a4af7315d23&contentType=text%2Fjavascript',
//              '/Game/GetResource?resourceID=6b7ce3b4-695a-46f0-a5b8-382f86ba63be&contentType=text%2Fjavascript',
//              '/Game/GetResource?resourceID=b3739128-ecb8-4524-961f-e1a66d154a79&contentType=text%2Fjavascript');

//self.addEventListener('message', function (e) {
//    var data = e.data;

//    var minMax = new AzureGames.MinMaxAI();
//    //AzureGames.ApplyOpponentMove(minMax.playTurn(board, player));

//    postMessage(minMax.playTurn(board, player));
//}, false);


AzureGames.Opponent = function (callback, board, player) {
    var minMax = new AzureGames.MinMaxAI();
    
    callback(minMax.playTurn(board, player));
}

AzureGames.MinMaxAI = Class.extend({    
    init: function () {        
    },
    playTurn: function (board, player) {
        AzureGames.MinMaxAI.StartTime = new Date();
        AzureGames.MinMaxAI.NodesEvaluated = 0;
        AzureGames.MinMaxAI.DepthReached = 0;

        var bestMove = Iterate(board, AzureGames.MinMaxAI.MaxDepth, player);

        AzureGames.MinMaxAI.ElapsedTime = new Date() - AzureGames.MinMaxAI.StartTime;

        if (AzureGames.MinMaxAI.ElapsedTime < AzureGames.MinMaxAI.MaxTime)
            AzureGames.MinMaxAI.MaxDepth++;

        return bestMove;

        function Iterate(board, depth, player) {
            var elapsedTime = new Date() - AzureGames.MinMaxAI.StartTime;

            if (depth == 0 // true if reached max depth
                || board.isFinalState() // true if board is in an end state
                    || (elapsedTime > AzureGames.MinMaxAI.MaxTime && depth != AzureGames.MinMaxAI.MaxDepth) // run out of time and we have explored the first turn
                ) {
                AzureGames.MinMaxAI.NodesEvaluated++;
                if ((AzureGames.MinMaxAI.MaxDepth - depth) > AzureGames.MinMaxAI.DepthReached)
                    AzureGames.MinMaxAI.DepthReached = AzureGames.MinMaxAI.MaxDepth - depth;

                return board.value;
            }

            var moves = board.getMoves(player);

            //            if (moves.length == 0) {
            //                return board.value;
            //            }

            var bestMove;
            var value = player == 0 ? -99999 : 99999;

            $.each(moves, function () {                
                var childBoard = board.copyBoard();
                childBoard.applyMove(this, player);

                var childvalue = Iterate(childBoard, depth - 1, player == 1 ? 0 : 1);

                if ((player == 0 && value < childvalue)
                    || (player == 1 && value > childvalue)) {
                    value = childvalue;
                    bestMove = this;
                }
            });

                        if (typeof bestMove == 'undefined') {
                            // hack until this is figured out
                            bestMove = moves[0];
                        }

            return bestMove;
        }
    }
});


// static properties of MinMaxAI
AzureGames.MinMaxAI.NodesEvaluated = 0;
AzureGames.MinMaxAI.MaxDepth = 2;
AzureGames.MinMaxAI.MaxTime = 6000;
AzureGames.MinMaxAI.StartTime = new Date();
AzureGames.MinMaxAI.ElapsedTime = 0;
AzureGames.MinMaxAI.DepthReached = 0;